package com.ywl.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ywl.pojo.Admin;
import com.ywl.pojo.LoginForm;
import com.ywl.pojo.Student;
import com.ywl.pojo.Teacher;
import com.ywl.service.AdminService;
import com.ywl.service.StudentService;
import com.ywl.service.TeacherService;
import com.ywl.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;


/**
 * @author DL5O
 * @version 1.0
 */
@Api(tags = "系统控制器")
@RestController//   不是@Controller，异步Controller
@RequestMapping("/sms/system")
public class SystemController {

    @Autowired
    private AdminService adminService;//自动注入adminService
    @Autowired
    private StudentService studentService;
    @Autowired
    private TeacherService teacherService;


    //修改密码
    /*Post /sms/system/updatePwd/123456/1234567
    *      /sms/system/updatePwd/{oldPassword}/{newPassword}
    * 请求参数:
         oldPassword
         newPassword
         token 头
      响应的数据:
         Result OK data=null
    * */
    @ApiOperation("更新用户密码的方法")
    @PostMapping("/updatePwd/{oldPwd}/{newPwd}")
    public Result updatePwd(
            @ApiParam("oldPwd") @PathVariable("oldPwd") String oldPwd,
            @ApiParam("newPwd") @PathVariable("newPwd") String newPwd,
            @ApiParam("token")@RequestHeader("token") String token
    ){

        boolean expiration = JwtHelper.isExpiration(token);
        if(expiration){
            //token 过期
            return Result.fail().message("token失效，请重新登陆");
        }

        //获取用户id和用户类型
        Integer userId = JwtHelper.getUserId(token).intValue();
        Integer userType = JwtHelper.getUserType(token);

        oldPwd = MD5.encrypt(oldPwd);
        newPwd = MD5.encrypt(newPwd);
        switch (userType){
            case 1:
                QueryWrapper<Admin> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("id",userId);
                queryWrapper1.eq("password",oldPwd);
                Admin admin = adminService.getOne(queryWrapper1);
                if(admin!=null){
                    //进行修改操作
                    admin.setPassword(newPwd);
                    adminService.saveOrUpdate(admin);
                }else{
                    return Result.fail().message("原密码有误");
                }
                break;
            case 2:
                QueryWrapper<Student> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("id",userId);
                queryWrapper2.eq("password",oldPwd);
                Student student = studentService.getOne(queryWrapper2);
                if(student!=null){
                    //进行修改操作
                    student.setPassword(newPwd);
                    studentService.saveOrUpdate(student);
                }else{
                    return Result.fail().message("原密码有误");
                }
                break;
            case 3:
                QueryWrapper<Teacher> queryWrapper3 = new QueryWrapper<>();
                queryWrapper3.eq("id",userId);
                queryWrapper3.eq("password",oldPwd);
                Teacher teacher = teacherService.getOne(queryWrapper3);
                if(teacher!=null){
                    //进行修改操作
                    teacher.setPassword(newPwd);
                    teacherService.saveOrUpdate(teacher);
                }else{
                    return Result.fail().message("原密码有误");
                }
                break;
        }
        return Result.ok();
    }


    // POST /sms/system/headerImgUpload
    @ApiOperation("文件上传统一路口")
    @PostMapping("/headerImgUpload")
    public Result headerImgUpload(
            @ApiParam("要上传的头像文件") @RequestPart("multipartFile") MultipartFile multipartFile,
            HttpServletRequest request
    ) {
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        String originalFilename = multipartFile.getOriginalFilename();
        int i = originalFilename.lastIndexOf(".");
        String newFilename = uuid.concat(originalFilename.substring(i));

        //保存文件 将文件发送到第三方/独立的图片服务器上去
        String portraitPath = "D:/Practice/SpringBoot/zhxy/target/classes/public/upload/".concat(newFilename);
        try {
            multipartFile.transferTo(new File(portraitPath));
        } catch (IOException e) {
            //e.printStackTrace();
            throw new RuntimeException(e);
        }
        //响应一个图片路径
        String path = "upload/".concat(newFilename);
        return Result.ok(path);
    }

    @ApiOperation("通过token口令获取当前登陆的用户信息的方法")
    @GetMapping("/getInfo")
    public Result getInfoByToken(@ApiParam("token")@RequestHeader("token") String token/*接受请求并存入到token里面*/) {
        //验证token是否过期
        boolean expiration = JwtHelper.isExpiration(token);
        if (expiration) { //如果过期
            return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
        }

        //从token中解析出用户id和用户类型
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);

        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        //判断用户的类型
        switch (userType) {
            case 1:
                Admin admin = adminService.getAdminById(userId);
                map.put("userType", 1);
                map.put("user", admin);
                break;
            case 2:
                Student student = studentService.getStudentById(userId);
                map.put("userType", 2);
                map.put("user", student);
                break;
            case 3:
                Teacher teacher = teacherService.getTeacherById(userId);
                map.put("userType", 3);
                map.put("user", teacher);
                break;
        }

        return Result.ok(map);
    }

    @ApiOperation("登陆的方法")
    @PostMapping("/login")
    public Result login(@ApiParam("登录提交的信息的form表单") @RequestBody LoginForm loginForm /* 把json格式字符串转化为loginForm*/, HttpServletRequest request, HttpServletResponse response) {
        // 验证码问题校验
        HttpSession session = request.getSession();
        String sessionVerifiCode = (String) session.getAttribute("verifiCode");
        String loginVerifiCode = loginForm.getVerifiCode();

        if ("".equals(sessionVerifiCode) || null == sessionVerifiCode) {
            //如果没有输入该验证码，或者验证码失效了
            return Result.fail().message("验证码失效，请刷新后重试");
        }

        if (!sessionVerifiCode.equalsIgnoreCase(loginVerifiCode)) {
            return Result.fail().message("验证码有误,请重新输入");
        }

        // 从session域中依次现有验证码
        session.removeAttribute("verifiCode");

        // 分用户类型进行校验
        // 准备一个map用户存放响应的数据
        Map<String, Object> map = new LinkedHashMap<>();
        switch (loginForm.getUserType()) {
            case 1:
                //管理员
                try {
                    Admin admin = adminService.login(loginForm);//在数据库中查找用户信息
                    if (null != admin) {
                        // 用户的类型和用户的id转换为一个密文以token的名称向客户端反馈
                        String token = JwtHelper.createToken(admin.getId().longValue(), 1);
                        map.put("token", token);
                    } else {
                        throw new RuntimeException("用户名或者密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 2:
                //学生
                try {
                    Student student = studentService.login(loginForm);//在数据库中查找用户信息
                    if (null != student) {
                        // 用户的类型和用户的id转换为一个密文以token的名称向客户端反馈
                        String token = JwtHelper.createToken(student.getId().longValue(), 2);
                        map.put("token", token);
                    } else {
                        throw new RuntimeException("用户名或者密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 3:
                //学生
                try {
                    Teacher teacher = teacherService.login(loginForm);//在数据库中查找用户信息
                    if (null != teacher) {
                        // 用户的类型和用户的id转换为一个密文以token的名称向客户端反馈
                        String token = JwtHelper.createToken(teacher.getId().longValue(), 3);
                        map.put("token", token);
                    } else {
                        throw new RuntimeException("用户名或者密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
        }
        return Result.fail().message("查无此用户");
    }

    @RequestMapping("/getVerifiCodeImage")
    public void getVerifiCodeImage(HttpServletRequest request, HttpServletResponse response) {
        //获取图片
        BufferedImage verifiCodeImage = CreateVerifiCodeImage.getVerifiCodeImage();
        //获取图片上的验证码
        String verifiCode = new String(CreateVerifiCodeImage.getVerifiCode());//将char数组转换为String
        System.out.println(verifiCode);
        //将验证码文本放入session域，为下一次验证做准备
        HttpSession session = request.getSession();
        session.setAttribute("verifiCode", verifiCode);
        //将验证码响应给浏览器
        try {
            ImageIO.write(verifiCodeImage, "JPEG", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
